<html>
    <head>
        <title>API Promise化</title>
    </head>
    <body>
        <script>
            /*
                五、API Promise 化

                            1、具体 API Promise 化的策略：

                                    ①、异步的方法，如果不传入success、fail、complete 等callback参数，将以Promise返回数据。  

                                            例如：  uni.getImageInfo()

                                    ②、异步的方法，且有返回对象，如果希望获取返回对象，必须至少传入一项  success、fail、complete 等 callback 参数。

                                            例如：

                                                // 正常使用
                                                const task = uni.connectSocket({
                                                    success(res){
                                                        console.log(res)
                                                    }
                                                })

                                                // Promise 化
                                                uni.connectSocket().tnen(res=>{
                                                    // 此处即为正常使用是 success 回调的 res
                                                    // uni.connectSocket() 正常使用时是会返回 task 对象的，如果想获取 task， 则不要使用 Promise 化

                                                })

                            2、不进行 Promise 化的API：

                                            ①、同步的方法 （即以sync结束）。  例如：  uni.getSystemInfoSync()

                                            ②、以 create 开头的方法。 例如： uni.createMapContext()

                                            ③、以 manager 结束的方法。 例如： uni.getBackgroundAudioManager()


                            3、Vue2 和 Vue3 的API Promise化

                                         Vue2 和 Vue3 项目中 API Promise化 返回格式不一致，以下为 "不同点"  和  "返回个数互相转化"   

                                      <1>、不同点

                                                ①、Vue2 对部分 API 进行了 Promise 封装，返回数据的第一个参数是错误对象，第二个参数是返回数据。
                                                
                                                   此时使用 catch 是拿不到报错信息的，因为内部对错误进行了拦截。

                                                ②、Vue3 对部分 API 进行了 Promise 封装，调用成功会进入 then 方法 回调。调用失败会进入 catch 方法 回调


                                               // vue2 示例：

                                                            ★、 默认方式
                                                                uni.request({
                                                                    url: "https://www.example.com/request",
                                                                    success: (res) => {
                                                                        console.log(res.data);
                                                                    },
                                                                    fail: (err) => {
                                                                        console.error(err);
                                                                    },
                                                                });

                                                            ★、 Promise 
                                                                uni.request({
                                                                    url: "https://www.example.com/request",
                                                                })
                                                                .then((data) => {
                                                                    // data为一个数组
                                                                    // 数组第一项为错误信息 ,即为 fail 回调
                                                                    // 第二项为返回数据
                                                                    var [err, res] = data;
                                                                    console.log(res.data);
                                                                });

                                                            ★、Await
                                                                async function request() {
                                                                    var [err, res] = await uni.request({
                                                                        url: "https://www.example.com/request",
                                                                    });
                                                                    console.log(res.data);
                                                                }

                                                // Vue3 示例：

                                                            ★、默认方式
                                                                    uni.request({
                                                                        url: "https://www.example.com/request",
                                                                        success: (res) => {
                                                                            console.log(res.data);
                                                                        },
                                                                        fail: (err) => {
                                                                            console.error(err);
                                                                        },
                                                                    });

                                                            ★、使用 Promise then/catch 方式调用
                                                                    uni.request({
                                                                        url: "https://www.example.com/request",
                                                                    })
                                                                    .then((res) => {
                                                                        // 此处的 res 参数，与使用默认方式调用时 success 回调中的 res 参数一致
                                                                        console.log(res.data);
                                                                    })
                                                                    .catch((err) => {
                                                                        // 此处的 err 参数，与使用默认方式调用时 fail 回调中的 err 参数一致
                                                                        console.error(err);
                                                                    });

                                                            
                                                            ★、使用 Async/Await 方式调用
                                                                    async function request() {
                                                                        try {
                                                                            var res = await uni.request({
                                                                            url: "https://www.example.com/request",
                                                                            });
                                                                            // 此处的 res 参数，与使用默认方式调用时 success 回调中的 res 参数一致
                                                                            console.log(res);
                                                                        } catch (err) {
                                                                            // 此处的 err 参数，与使用默认方式调用时 fail 回调中的 err 参数一致
                                                                            console.error(err);
                                                                        }
                                                                    }

                            <3>、返回格式互相转化

                                        
                                                // Vue 2 转 Vue 3, 在 main.js 中写入以下代码即可
                                                    function isPromise(obj) {
                                                    return (
                                                        !!obj &&
                                                        (typeof obj === "object" || typeof obj === "function") &&
                                                        typeof obj.then === "function"
                                                    );
                                                    }

                                                    uni.addInterceptor({
                                                        returnValue(res) {
                                                            if (!isPromise(res)) {
                                                            return res;
                                                            }
                                                            return new Promise((resolve, reject) => {
                                                            res.then((res) => {
                                                                if (!res) {
                                                                resolve(res);
                                                                return;
                                                                }
                                                                if (res[0]) {
                                                                reject(res[0]);
                                                                } else {
                                                                resolve(res[1]);
                                                                }
                                                            });
                                                            });
                                                        },
                                                    });


                                                // Vue 3 转 Vue 2, 在 main.js 中写入以下代码即可
                                                    function isPromise(obj) {
                                                    return (
                                                        !!obj &&
                                                        (typeof obj === "object" || typeof obj === "function") &&
                                                        typeof obj.then === "function"
                                                    );
                                                    }

                                                    uni.addInterceptor({
                                                        returnValue(res) {
                                                            if (!isPromise(res)) {
                                                            return res;
                                                            }
                                                            const returnValue = [undefined, undefined];
                                                            return res
                                                            .then((res) => {
                                                                returnValue[1] = res;
                                                            })
                                                            .catch((err) => {
                                                                returnValue[0] = err;
                                                            })
                                                            .then(() => returnValue);
                                                        },
                                                    });
            */  
        </script>
    </body>
</html>